package com.base.cn.platform.os.service.manage.loreset;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.service.CommonSetSubjectDataService;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.dao.manage.loreset.SysLoresetDao;
import com.base.cn.platform.os.entity.manage.loreset.SysLoreset;
import com.base.cn.platform.os.entity.manage.loreset.SysLoresetPoint;
import com.base.cn.platform.os.entity.manage.subject.SysSubject;
import com.base.cn.platform.os.entity.manage.user.SysUser;
import com.base.cn.platform.os.service.manage.subject.SysSubjectBiz;
import com.base.cn.platform.os.service.manage.user.SysUserBiz;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 知识体系Biz
 *
 * @author s.li
 * @create 2018-03-22 17:26
 */
@Service
public class SysLoresetBiz extends BaseBiz<SysLoreset,SysLoresetDao> {

    @Autowired
    private SysSubjectBiz sysSubjectBiz;
    @Autowired
    private SysUserBiz sysUserBiz;
    @Autowired
    private SysLoresetPointBiz sysLoresetPointBiz;
    @Autowired
    private CommonSetSubjectDataService<SysLoreset> commonSetSubjectDataService;

    /**
     * 修改知识体系状态
     * @param ids 知识体系ID串
     * @param status 状态，1正常，2禁用
     */
    public void updateLoresetStatus(String ids,int status){
        if(StringUtils.isNotEmpty(ids)){
            ids = ids = StringUtils.subHeadTailString(ids,",");
            if(StringUtils.isNotEmpty(ids)){
                SysLoreset loreset = new SysLoreset();
                loreset.setStatus(status);
                this.updateByWhereSql(loreset," id in ("+ids+")");
            }
        }
    }

    /**
     * 删除知识体系
     * @param loresetIds 知识体系ID串
     */
    /*@Transactional(rollbackFor = IllegalArgumentException.class)
    public void deleteLoreset(String loresetIds){
        if(StringUtils.isNotEmpty(loresetIds)){
            loresetIds = StringUtils.subHeadTailString(loresetIds,",");
            if(StringUtils.isNotEmpty(loresetIds)){
                this.deleteWhereSql(" id in ("+loresetIds+")");
                sysLoresetPointBiz.deleteWhereSql(" loresetId in ("+loresetIds+")");
            }
        }
    }*/

    /**
     * 保存知识体系数据
     * @param loreset 知识体系数据对象
     * @return SysLoreset
     */
    public SysLoreset saveLoreset(SysLoreset loreset){
        //添加
        if(loreset.getId()==null || loreset.getId().compareTo(new BigDecimal(0)) <= 0){
            loreset.setStatus(1);
            this.save(loreset);
        }else{//修改
            SysLoreset _loreset = this.findById(loreset.getId());
            _loreset.setLoresetName(loreset.getLoresetName());
            _loreset.setSubjectIds(loreset.getSubjectIds());
            this.updateById(_loreset,null);
            return _loreset;
        }
        return loreset;
    }

    /**
     * 通过ID串
     * @param ids 知识体系ID串
     * @param subjectData 是否设置专业数据，true设置，false不设置
     * @param sysUserData 是否设置创建人数据，true设置，false不设置
     * @param pointData 是否设置知识点数据，true设置，false不设置
     * @return 返回当前页的知识体系列表
     */
    public List<SysLoreset> findLorestListByIds(String ids,boolean subjectData,boolean sysUserData,boolean pointData){
        if(StringUtils.isNotEmpty(ids)){
            ids = StringUtils.subHeadTailString(ids,",");
            if(StringUtils.isNotEmpty(ids)){
                List<SysLoreset> loresetList = this.find(" id in ("+ids+")",null,null);
                loresetList = this.setSysSubjectAndSysUserOrPoint(loresetList,subjectData,sysUserData,pointData);
                return loresetList;
            }
        }
        return null;
    }

    /**
     * 通过ID串
     * @param ids 知识体系ID串
     * @param subjectData 是否设置专业数据，true设置，false不设置
     * @param sysUserData 是否设置创建人数据，true设置，false不设置
     * @param pointData 是否设置知识点数据，true设置，false不设置
     * @return 返回当前页的知识体系列表
     */
    @RequestMapping("/findLorestListByIdsToMap")
    public Map<BigDecimal, SysLoreset> findLorestListByIdsToMap(String ids,
                                                                boolean subjectData,
                                                                boolean sysUserData,
                                                                boolean pointData){
        List<SysLoreset> sysLoresetList = this.findLorestListByIds(ids, subjectData, sysUserData, pointData);
        return sysLoresetList == null ? Collections.emptyMap() :
                sysLoresetList.stream().collect(Collectors.toMap(SysLoreset::getId, Function.identity()));
    }

    /**
     * 获取知识体系下的知识点，且分层（用于考试）
     * @param subjectIds 专业ID串
     * @param loresetData 是否设置知识点的知识体系
     * @return List<SysLoresetPoint>
     */
    public List<SysLoresetPoint> findLayeredSysExamLoresetPointList(String subjectIds, boolean loresetData){
        List<SysLoreset> sysLoresetList = this.findLorestListBySysSubjectIds(subjectIds,false,false,false);
        if(ObjectUtils.isNotEmpty(sysLoresetList)){
            String loresetIds = sysLoresetList.stream().map(e->e.getId().toString()).distinct().collect(Collectors.joining(","));
            List<SysLoresetPoint> sysLoresetPointList = sysLoresetPointBiz.findLayeredLoresetPoint(loresetIds,loresetData);
            return sysLoresetPointList;
        }
        return null;
    }

    /**
     * 通过专业ID串
     * @param subjectIds 专业ID串
     * @param subjectData 是否设置专业数据，true设置，false不设置
     * @param sysUserData 是否设置创建人数据，true设置，false不设置
     * @param pointData 是否设置知识点数据，true设置，false不设置
     * @return 返回当前页的知识体系列表
     */
    public List<SysLoreset> findLorestListBySysSubjectIds(String subjectIds,boolean subjectData,boolean sysUserData,boolean pointData){
        if(StringUtils.isNotEmpty(subjectIds)){
            subjectIds = DataUtil.filterNotNumberStr(subjectIds);
            if(StringUtils.isNotEmpty(subjectIds)){
                String subjectWhereSql = StringUtils.getSubjectSql("subjectIds",subjectIds);
                StringBuilder stringBuilder = new StringBuilder(" status !=3 ");
                stringBuilder.append(subjectWhereSql);
                List<SysLoreset> loresetList = this.find(stringBuilder.toString(),null,null);
                loresetList = this.setSysSubjectAndSysUserOrPoint(loresetList,subjectData,sysUserData,pointData);
                return loresetList;
            }
        }
        return null;
    }

    /**
     * 分页获取知识体系列表
     * @param page 分页条件
     * @param loreset 查询条件对
     * @param subjectData 是否设置专业数据，true设置，false不设置
     * @param sysUserData 是否设置创建人数据，true设置，false不设置
     * @param pointData 是否设置知识点数据，true设置，false不设置
     * @return 返回当前页的知识体系列表
     */
    public PageInfo<SysLoreset> findLoresetList(Pagination page,
                                             SysLoreset loreset,
                                             boolean subjectData,
                                             boolean sysUserData,
                                             boolean pointData){
        StringBuilder whereSql = new StringBuilder(" status !=3");
        if(ObjectUtils.isNotEmpty(loreset)){
            if(ObjectUtils.isNotEmpty(loreset.getStatus())){
                whereSql .append(" and status = ").append(loreset.getStatus());
            }
            if(StringUtils.isNotEmpty(loreset.getLoresetName())){
                whereSql .append( " and loresetName like '%").append(loreset.getLoresetName().trim()).append("%'");
            }
            if(StringUtils.isNotEmpty(loreset.getSubjectIds())){
                whereSql .append( StringUtils.getSubjectSql("subjectIds",loreset.getSubjectIds()));
            }
            whereSql .append(" order by createTime desc");
        }
        PageInfo<SysLoreset> loresetPageInfo = this.findPage(whereSql.toString(),page,null);

        //设置专业,建用户数据
        loresetPageInfo.setList(this.setSysSubjectAndSysUserOrPoint(loresetPageInfo.getList(),subjectData,sysUserData,pointData));
        return loresetPageInfo;
    }

    /**
     * 通过ID获取知识体系对象
     * @param id 知识体系ID
     * @param subjectData 是否设置专业数据，true设置，false不设置
     * @param sysUserData 是否设置创建人数据，true设置，false不设置
     * @param pointData 是否设置知识点数据，true设置，false不设置
     * @return SysLoreset
     */
    public SysLoreset findById(BigDecimal id,boolean subjectData,boolean sysUserData,boolean pointData){
        SysLoreset loreset = this.findById(id);
        loreset = this.setSysSubjectAndSysUserOrPoint(loreset,subjectData,sysUserData,pointData);
        return loreset;
    }


    /**
     * 设置专业、用户、知识点
     * @param loreset
     * @param subjectData
     * @param sysUserData
     * @param pointData
     * @return SysLoreset
     */
    private SysLoreset setSysSubjectAndSysUserOrPoint(SysLoreset loreset, boolean subjectData, boolean sysUserData, boolean pointData){
        if(subjectData){
            loreset = this.setLoresetSysSubject(loreset);
        }
        if(sysUserData){
            loreset = this.setLoresetSysUser(loreset);
        }
        if(pointData){
            loreset = this.setSysLoresetPoint(loreset);
        }
        return loreset;
    }

    /**
     * 设置专业、用户、知识点
     * @param loresetList
     * @param subjectData
     * @param sysUserData
     * @param pointData
     * @return List<SysLoreset>
     */
    private List<SysLoreset> setSysSubjectAndSysUserOrPoint(List<SysLoreset> loresetList, boolean subjectData, boolean sysUserData, boolean pointData){
        if(subjectData){
            loresetList = this.setLoresetSysSubject(loresetList);
        }
        if(sysUserData){
            loresetList = this.setLoresetSysUser(loresetList);
        }
        if(pointData){
            loresetList = this.setSysLoresetPoint(loresetList);
        }
        return loresetList;
    }

    /**
     * 设置知识体系的知识点列表
     * @param loreset 知识体系
     * @return SysLoreset
     */
    private SysLoreset setSysLoresetPoint(SysLoreset loreset){
        if(ObjectUtils.isNotEmpty(loreset)){
            List<SysLoreset> loresetList = new ArrayList<>();
            loresetList.add(loreset);
            this.setSysLoresetPoint(loresetList);
            loreset = loresetList.get(0);
        }
        return loreset;
    }

    /**
     * 设置知识体系的知识点列表
     * @param loresetList 知识体系列表
     * @return List<SysLoreset>
     */
    private List<SysLoreset> setSysLoresetPoint(List<SysLoreset> loresetList){
        if(ObjectUtils.isNotEmpty(loresetList)){
            String loresetIds = loresetList.stream().map(e->e.getId().toString()).collect(Collectors.joining(","));
            Map<BigDecimal,List<SysLoresetPoint>> loresetPointListMap = sysLoresetPointBiz.findLayeredLoresetPoint(loresetIds);
            if(ObjectUtils.isNotEmpty(loresetPointListMap)){
                loresetList.forEach(e->{
                    List<SysLoresetPoint> loresetPointList = loresetPointListMap.get(e.getId());
                    e.setLoresetPointList(loresetPointList);
                });
            }
        }
        return loresetList;
    }

    /**
     * 设置知识体系列表的专业数据
     * @param loreset 知识体系数据列表
     */
    private SysLoreset setLoresetSysSubject(SysLoreset loreset){
        if(ObjectUtils.isNotEmpty(loreset)){
            List<SysLoreset> loresetList = new ArrayList<>();
            loresetList.add(loreset);
            loresetList = this.setLoresetSysSubject(loresetList);
            loreset = loresetList.get(0);
        }
        return loreset;
    }

    /**
     * 设置知识体系列表的专业数据
     * @param loresetList 知识体系数据列表
     */
    private List<SysLoreset> setLoresetSysSubject(List<SysLoreset> loresetList){
        if(ObjectUtils.isNotEmpty(loresetList)){
            String subjectIds = commonSetSubjectDataService.getSubjectIds(loresetList);
            //获取专业Map
            Map<BigDecimal,SysSubject> subjectMaps = sysSubjectBiz.findSubjectListByIds(subjectIds);
            if(ObjectUtils.isNotEmpty(subjectMaps)){
                commonSetSubjectDataService.setSubjectData(subjectMaps,loresetList);
            }
        }
        return loresetList;
    }

    /**
     * 设置知识体系创建人数据
     * @param loreset
     */
    private SysLoreset setLoresetSysUser(SysLoreset loreset){
        if(ObjectUtils.isNotEmpty(loreset)){
            List<SysLoreset> loresetList = new ArrayList<>();
            loresetList.add(loreset);
            loresetList = this.setLoresetSysUser(loresetList);
            loreset = loresetList.get(0);
        }
        return loreset;
    }

    /**
     * 设置知识体系创建人数据
     * @param loresetList
     */
    private List<SysLoreset> setLoresetSysUser(List<SysLoreset> loresetList){
        if(ObjectUtils.isNotEmpty(loresetList)){
            String userIds = loresetList.stream().map(e->e.getCreateUserId().toString()).collect(Collectors.joining(","));
            Map<BigDecimal,SysUser> sysUserMap = sysUserBiz.findSysUserByIds(userIds);
            if(ObjectUtils.isNotEmpty(sysUserMap)){
                loresetList.stream().forEach(e->{
                    e.setSysUser(sysUserMap.get(e.getCreateUserId()));
                });
            }
        }
        return loresetList;
    }
}
